iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0

這篇要介紹 AutoScalar 的工具,Karpenter 這邊部分會分成三個部分講解,這個對 AWS 的使用者可能是很大的福音,因為它可以做到 Scale for GPU nodes,如果對於 AWS 比較熟的 Architecture 都知道AWS 現成的 Autoscaler可以使用,而 Autoscaler 也是真的不錯,至少不會讓 EC2 Node 變成 zombie 卡在那邊,但 Karpenter 沒設定好的話很容易造成 zombie node。

Why AWS Auto-Scaler CAN NOT schedule GPU to Scale up/in?

AutoScaler 這個工具只能對 Cpu Metrics 做調整,不是不難想像也很直覺,因為 CPU 的使用率可以用內建用頻率來代表使用率,但是對於 GPU 而言,GPU 在做 Shared 的部分則是 Memory 的切片,這邊就需要切 Memory Address,這個Memory shared OS 那邊沒辦法控制,所以這也是為什麼 GPU 沒辦法很彈性使用的部分。

What is Kubernetes CRDs?

前面補充完OS的基本知識後,我們再回來 Karpenter 的部分,但是再說明 Karpenter 之前,要先在說明一下 kubernetes 上面的 CRDs (Custom Resource Definition),簡單來講就是在 k8s 內部先宣要( Definition ) 要部署的 Resource,這樣就很清楚可以了解了。

因為在 k8s 上面要 Apply yml file, which content must has kind this attribute,所以要先讓 kubernetes 可以了解你的 kind 是什麼類別,所以就會透過 CRDs 來建立,另外CRDs 怎麼寫,可能真的要問 k8s 的大師才能跟解釋,我這邊也是站在巨人的肩膀上直接使用起來!!

另外建立 k8s CRDs, 的話通常指令可以用 create 比較好建立,也不會出錯誤,例如下方:

kubectl create -f .../k8s_crds.yml

如果有安裝 OpenLens 的話基本上也可以在下面看到

Install Karpenter through Helm

可以使用上面的 kubectl create 來建立 CDRs ,但是官方的案例是使用 Helm 來建立,所以我覺得用 Helm 比較完整,所以就看下方的部分直接使用 helm 來安裝

# Logout of helm registry to perform an unauthenticated pull against the public ECR
helm registry logout public.ecr.aws

helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter --version ${KARPENTER_VERSION} --namespace karpenter --create-namespace \
  --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \
  --set settings.aws.clusterName=${CLUSTER_NAME} \
  --set settings.aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \
  --set settings.aws.interruptionQueueName=${CLUSTER_NAME} \
  --set controller.resources.requests.cpu=1 \
  --set controller.resources.requests.memory=1Gi \
  --set controller.resources.limits.cpu=1 \
  --set controller.resources.limits.memory=1Gi \
  --wait

以下就是說明 要先安裝 的重要性,如果沒有宣告就會找不到要怎麼用。

Karpenter creates a mapping between CloudProvider machines and CustomResources in the cluster for capacity tracking. To ensure this mapping is consistent, Karpenter utilizes the following tag keys:

  • karpenter.sh/managed-by
  • karpenter.sh/provisioner-name
  • kubernetes.io/cluster/${CLUSTER_NAME}

AWS EC2 Node

在使用的Karpenter 這邊要先說明一下, Karpenter 其實可以建立其他的cloud provider 的 node,所以這邊接下來都是使用 AWS EC2 的作為範例說明

另外說到 AWS Computing Resource 最基本的概念就是 EC2 ,所以 Karpenter 這邊也是預設建立 EC2 來當 Node Template

AWS NodeTemplate

AWS NodeTemplate 這個 component 就是在 k8s 裡面中,我要怎麼去尻一個 EC2 的node 得出來,這邊就很簡單,不難理解,我就在程式碼上面打上註解。

File: AwsNodeTemplate.yml

apiVersion: karpenter.k8s.aws/v1alpha1 #這就是宣告的Api
kind: AWSNodeTemplate 
metadata:
  name: default # 這個很重要,因為下面的 Provisioner 靠這個去找的
spec:
	amiFamily: Bottlerocket # 這就是選擇ami 的部分
  subnetSelector:
    karpenter.sh/discovery: ${CLUSTER_NAME}
  securityGroupSelector:
    karpenter.sh/discovery: ${CLUSTER_NAME}

不過要注意的是 subnetSelectorSecurityGroupSelector 這兩個可能比較奇怪,因為 EC2 在建立的時候一定要選擇 Subnet and Security Group 所以那個設定就是會自動去抓取 有設 那個 tag 在上面的 subnet and security group

詳細可以看這邊的設置:https://karpenter.sh/docs/concepts/node-templates/

Provisioner

再來就是講 Provisioner ,這邊的概念就比較簡單,可以想像上面是選擇 EC2 基本的設置,而 Provisioner 的部分就是選擇要 EC2 哪個機型,然後設置 CPU 的總數量跟型號 ,當然還有設置要用哪一組 AWSNodeTemplate 設定, 不過最重要的事這邊要設置 Taint 但是為什麼要設置 Taint 的話,不知道 Taint 跟 Torelation 的部分的話,我們之後會講。

File: Provisioner.yml

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
	requirements:
    - key: "karpenter.k8s.aws/instance-category"
      operator: In
      values: ["c", "m", "r"] # instance種類
    - key: "karpenter.k8s.aws/instance-cpu"
      operator: In
      values: ["4", "8", "16", "32"] #cpu 數量
    - key: "karpenter.k8s.aws/instance-hypervisor"
      operator: In
      values: ["nitro"]
    - key: "karpenter.k8s.aws/instance-generation"
      operator: Gt
      values: ["2"] #c2, m2 ,r2
    - key: "kubernetes.io/arch"
      operator: In
      values: ["arm64", "amd64"] # amd64 or arm 架構
    - key: "karpenter.sh/capacity-type" # If not included, the webhook for the AWS cloud provider will default to on-demand
      operator: In
      values: ["spot", "on-demand"] # 開這個要確定已經可以使用 ec2 spot instance,不知道怎麼設定看前面幾張文章
  limits:
    resources:
      cpu: 1000 # 這邊會限制種量
  providerRef:
    name: default # 這邊就剛剛設定的 AWSNodeTemplate metename
  consolidation: 
    enabled: true

	taints: # 這邊等等設置 pod 會需要使用
	    - key: example.com/special-taint
	      effect: NoSchedule

詳細的話可以看這篇的設置:https://karpenter.sh/docs/concepts/provisioners/

To be continued..


Reference

https://karpenter.sh/

https://aws.amazon.com/cn/blogs/china/karpenter-new-generation-kubernetes-auto-scaling-tools/


上一篇
{Day 14: AWS 101 - EC2 & EBS }
下一篇
{Day 16: AutoScalar Karpenter for AWS - part 2}
系列文
Don't be a Machine Learning Engineer30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言